
package com.rt.schedulenew.utils.jwt.util;

import org.slf4j.LoggerFactory;

import javax.crypto.SecretKey;
import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;

import com.rt.schedulenew.utils.util.JsonUtil;

import java.util.Base64;

import com.rt.schedulenew.utils.jwt.common.JwtToken;
import com.rt.schedulenew.utils.jwt.common.JwtValidInfo;
import org.slf4j.Logger;

public class JwtTokenUtil {
    private static Logger log;
    private static String DEFAULT_SECRET = "8757167d767d83c9967d92add1b7c7ca82927a78815c8a1c301b8e972978dd7c";
    public static String DEFAULT_CHARSET = "UTF-8";
    /**
     * token过期时间
     */
    private static Long DEFAULT_EXPIRY_TIME;

    /**
     * 生成token
     *
     * @param info
     * @return
     */
    public static String createToken(JwtValidInfo info) {
        if (info.getExpiryTime() == null) {
            info.setExpiryTime(JwtTokenUtil.DEFAULT_EXPIRY_TIME);
        }
        JwtToken token = new JwtToken();
        JwtToken.Header header = token.getHeader();
        header.setTyp("JWT");
        header.setAlg("HS256");

        JwtToken.Payload payload = token.getPayload();
        payload.setIss(info.getSysCode());
        payload.setSysCode(info.getSysCode());
        Long currentTime = System.currentTimeMillis();
        payload.setIat(currentTime);
        payload.setExp(currentTime + info.getExpiryTime());
        payload.setSessionId(info.getSessionId());
        payload.setUserId(info.getUserId());
        payload.setUserName(info.getUserName());
        payload.setType(info.getType());
        payload.setSysName(info.getSysName());
        StringBuffer buffer = new StringBuffer();
        String signature = "";
        String tokenStr;
        Base64.Encoder base64Encoder = Base64.getEncoder();
        String headerBase64Encode = base64Encoder.encodeToString(JsonUtil.toJson(header).getBytes());
        String payloadBase64Encode = base64Encoder.encodeToString(JsonUtil.toJson(payload).getBytes());
        buffer.append(headerBase64Encode).append(".").append(payloadBase64Encode);
        try {
            signature = encodeHmacSHA256(buffer.toString(), DEFAULT_SECRET.getBytes(DEFAULT_CHARSET));
        } catch (Exception e) {
            log.error(e.getMessage(), e);
            // e.printStackTrace();
        }
        tokenStr = buffer.append(".").append(signature).toString();
        return tokenStr;
    }

    public static boolean verifyToken(String token) {
        String[] tempArray = token.split("\\.");
        if (tempArray.length != 3) {
            JwtTokenUtil.log.error("token被篡改");
            return false;
        }
        Long currentTime = System.currentTimeMillis();
        JwtToken.Payload load = getPayloadInfo(token);
        if (load == null) {
            log.error("token被篡改");
            return false;
        }
        if (currentTime > load.getExp()) {
            log.error("token已失效");
            return false;
        }
        String tempToken = "";
        try {
//            String header = new String(Base64.getDecoder().decode(tempArray[0]));
//            String payload = new String(Base64.getDecoder().decode(tempArray[1]));
            StringBuffer buffer = new StringBuffer();
            buffer.append(tempArray[0]).append(".").append(tempArray[1]);
            tempToken = encodeHmacSHA256(buffer.toString(), DEFAULT_SECRET.getBytes(DEFAULT_CHARSET));
        } catch (Exception e) {
            log.error(e.getMessage(), e);
            e.printStackTrace();
        }
        return tempArray[2].equals(tempToken);
    }

    public static JwtToken.Payload getPayloadInfo(String token) {
        try {
            String[] tempArray = token.split("\\.");
            String tempPayload = new String(Base64.getDecoder().decode(tempArray[1]));
            JwtToken.Payload payload = JsonUtil.toBean(tempPayload, JwtToken.Payload.class);
            return payload;
        } catch (Exception e) {
            log.error("获取jwt中payload数据失败！token内容：{}", token);
            return null;
        }
    }

    public static String getSessionId(String token) {
        try {
            JwtToken.Payload payload = getPayloadInfo(token);
            return payload.getSessionId();
        } catch (Exception e) {
            log.error("获取jwt中payload数据失败！token内容：{}", token);
            return null;
        }
    }

    private static String encodeHmacSHA256(String data, byte[] key) {
        SecretKey secretKey = new SecretKeySpec(key, "HmacSHA256");
        try {
            Mac mac = Mac.getInstance(secretKey.getAlgorithm());
            mac.init(secretKey);
            return Base64.getEncoder().encodeToString(mac.doFinal(data.getBytes(DEFAULT_CHARSET)));
        } catch (Exception e) {
//            e.printStackTrace();
            log.error("加密失败！内容：" + data);
            return null;
        }
    }

    static {
        log = LoggerFactory.getLogger(JwtTokenUtil.class);
        DEFAULT_EXPIRY_TIME = 604800000L;
    }


//    public static void main(String[] args) {
//        String s = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE2NjM2NDU1MDE5NDIsImlhdCI6MTY2MzU1OTEwMTk0Miwic2Vzc2lvbklkIjoiZWQwOTcxZDctNzE3MC00ZjU2LWI3M2MtMmNmMDU4M2MzYzk1IiwidXNlcklkIjoiMDAwMTA1MjI1MyJ9";
//        encodeHmacSHA256(s,)
//    }
}
